<?php

namespace app\service;

use Firebase\JWT\JWT;
use Firebase\JWT\Key;
use think\facade\Config;

/**
 * 兼容版本的JWT服务类
 */
class JwtService
{
    // 默认过期时间（2小时）
    public static $ExpireTime = 7200;

    /**
     * 生成JWT Token
     * @param array $userInfo 用户信息
     * @return string
     */
    public static function createToken(array $userInfo): string
    {
        $key = self::getSecretKey();
        $time = time();
        
        $payload = [
            'iss' => 'wechat-merchant',           // 签发者
            'aud' => 'wechat-merchant-api',       // 接收者
            'iat' => $time,                       // 签发时间
            'nbf' => $time,                       // 生效时间
            'exp' => $time + self::$ExpireTime,   // 过期时间
            'jti' => uniqid('jwt_', true),        // JWT ID
            'user' => $userInfo                   // 用户信息
        ];
        
        return JWT::encode($payload, $key, 'HS256');
    }

    /**
     * 解析JWT Token
     * @param string $token
     * @return object
     * @throws \Exception
     */
    public static function parseToken(string $token): object
    {
        try {
            $key = self::getSecretKey();
            $decoded = JWT::decode($token, new Key($key, 'HS256'));
            
            // 验证签发者和接收者
            if (($decoded->iss ?? '') !== 'wechat-merchant' || 
                ($decoded->aud ?? '') !== 'wechat-merchant-api') {
                throw new \Exception('Token签发者或接收者不匹配');
            }
            
            return $decoded;
        } catch (\Exception $e) {
            throw new \Exception('Token验证失败: ' . $e->getMessage());
        }
    }
    
    /**
     * 验证JWT Token是否有效
     * @param string $token
     * @return bool
     */
    public static function validateToken(string $token): bool
    {
        try {
            self::parseToken($token);
            return true;
        } catch (\Exception $e) {
            return false;
        }
    }

    /**
     * 获取Token剩余有效时间
     * @param string $token
     * @return int 剩余秒数，-1表示已过期或无效
     */
    public static function getTokenTtl(string $token): int
    {
        try {
            $decoded = self::parseToken($token);
            $exp = $decoded->exp ?? 0;
            $remaining = $exp - time();
            return max(0, $remaining);
        } catch (\Exception $e) {
            return -1;
        }
    }

    /**
     * 从Token中提取用户信息
     * @param string $token
     * @return array
     * @throws \Exception
     */
    public static function getUserFromToken(string $token): array
    {
        $decoded = self::parseToken($token);
        return (array)($decoded->user ?? []);
    }

    /**
     * 检查Token是否即将过期
     * @param string $token
     * @param int $threshold 阈值（秒），默认30分钟
     * @return bool
     */
    public static function isTokenExpiringSoon(string $token, int $threshold = 1800): bool
    {
        $ttl = self::getTokenTtl($token);
        return $ttl > 0 && $ttl <= $threshold;
    }

    /**
     * 获取Token统计信息
     * @param string $token
     * @return array
     */
    public static function getTokenStats(string $token): array
    {
        try {
            $decoded = self::parseToken($token);
            $now = time();
            
            return [
                'valid' => true,
                'issued_at' => date('Y-m-d H:i:s', $decoded->iat ?? 0),
                'expires_at' => date('Y-m-d H:i:s', $decoded->exp ?? 0),
                'remaining_seconds' => max(0, ($decoded->exp ?? 0) - $now),
                'is_expired' => ($decoded->exp ?? 0) <= $now,
                'user_id' => $decoded->user->id ?? null,
                'user_openid' => $decoded->user->openid ?? null,
            ];
        } catch (\Exception $e) {
            return [
                'valid' => false,
                'error' => $e->getMessage(),
            ];
        }
    }

    /**
     * 获取密钥
     * @return string
     */
    private static function getSecretKey(): string
    {
        $key = Config::get('app.app_key', 'wechat_merchant_key');
        
        if (empty($key) || $key === 'wechat_merchant_key') {
            // 如果没有配置密钥，使用默认值（仅用于开发环境）
            return 'wechat_merchant_default_key_2024';
        }
        
        return $key;
    }
}
